package SentenceTranslator;

import Include.ASMConstructor;
import Common.REG;
import Include.TACLine;
import Common.TacOperandType;
import Common.POSTYPE;
import java.util.ArrayList;
import java.util.List;
import Main.SymbolManager;

public class MulTranslator {
    public List<String> ASMLines;
    public List<String> SentenceTranslate(SymbolManager SymbolManager_, TACLine TACLine_) {
        ASMLines = new ArrayList<String>();
        String str_dst = TACLine_.dst.value;
        String str_src1 = TACLine_.src1.value;
        String str_src2 = TACLine_.src2.value;

        String eax_val_pre = SymbolManager_.rvalue(REG.EAX);
        int eax_val_pre_mem;
        if (!SymbolManager_.useInfo(eax_val_pre, true).noUse()) {
            eax_val_pre_mem = SymbolManager_.avalueMem(eax_val_pre);
            if (eax_val_pre_mem == -1) {
                // 内存中没有位置, push 保存
                SymbolManager_.pushReg(REG.EAX, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", REG.EAX));
            } else {
                // 内存中有位置, 更新内存中的值
                ASMLines.add(ASMConstructor.construct_asm("mov", eax_val_pre_mem, REG.EAX));
            }
        }
        
        // EAX = src1 类似 assign
        if (TACLine_.src1.operType == TacOperandType.IMM) {
            // 如果 src1 是立即数
            ASMLines.add(ASMConstructor.construct_asm("mov", REG.EAX, str_src1));
        } else if (TACLine_.src1.operType == TacOperandType.VAR) {
            // 如果 src1 是变量，可能会是寄存器、栈、全局变量
            String encode_str_src1 = SymbolManager_.encodeVar(str_src1);
            POSTYPE pos = SymbolManager_.position(encode_str_src1);
            if (pos == POSTYPE.REG) {
                REG src_reg = SymbolManager_.avalueReg(encode_str_src1);
                ASMLines.add(ASMConstructor.construct_asm("mov", REG.EAX, src_reg));
            } else if (pos == POSTYPE.MEM) {
                int src_mem = SymbolManager_.avalueMem(encode_str_src1);
                ASMLines.add(ASMConstructor.construct_asm("mov", REG.EAX, src_mem));
            } else if (pos == POSTYPE.GLOBAL) {
                ASMLines.add(ASMConstructor.construct_asm("mov", REG.EAX, str_src1));
            } else {
                System.out.println("mul sentence: str1's pos wrong");
            }
            SymbolManager_.setAvalueReg(SymbolManager_.encodeVar(str_src1), REG.EAX);
        }

        // 找一个寄存器给 src2，给这个寄存器做备份
        REG reg_src2 = REG.EBX;
        String reg_src2_pre = SymbolManager_.rvalue(reg_src2);
        int mem_src2_pre;
        if (!SymbolManager_.useInfo(reg_src2_pre, true).noUse()) {
            mem_src2_pre = SymbolManager_.avalueMem(reg_src2_pre);
            if (mem_src2_pre == -1) {
                // 内存中没有位置，push 保存
                SymbolManager_.pushReg(reg_src2, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", reg_src2));
            } else {
                // 内存中有位置，更新内存中的值
                ASMLines.add(ASMConstructor.construct_asm("mov", Integer.toString(mem_src2_pre), reg_src2));
            }
        }

        // EBX = src2 类似 assign
        if (TACLine_.src2.operType == TacOperandType.IMM) {
            // 如果 src2 是 立即数
            ASMLines.add(ASMConstructor.construct_asm("mov", reg_src2, str_src2));
        } else if (TACLine_.src2.operType == TacOperandType.VAR) {
            // 如果 src2 是 变量，可能会是 寄存器、栈、全局变量
            String encode_str_src2 = SymbolManager_.encodeVar(str_src2);
            POSTYPE pos = SymbolManager_.position(encode_str_src2);
            if (pos == POSTYPE.REG) {
                REG src_reg = SymbolManager_.avalueReg(encode_str_src2);
                ASMLines.add(ASMConstructor.construct_asm("mov", reg_src2, src_reg));
            } else if (pos == POSTYPE.MEM) {
                int src_mem = SymbolManager_.avalueMem(encode_str_src2);
                ASMLines.add(ASMConstructor.construct_asm("mov", reg_src2, src_mem));
            } else if (pos == POSTYPE.GLOBAL) {
                ASMLines.add(ASMConstructor.construct_asm("mov", reg_src2, str_src2));
            } else {
                System.out.println("mul sentence: str2's pos wrong");
            }
        }
        SymbolManager_.setAvalueReg(SymbolManager_.encodeVar(str_src2), reg_src2);
        
        // 备份 EAX 中的 src1
        String eax_src1 = SymbolManager_.rvalue(REG.EAX);
        Integer eax_src1_mem = null;
        if (!SymbolManager_.useInfo(eax_src1, true).noUse()) {
            eax_src1_mem = SymbolManager_.avalueMem(eax_src1);
            if (eax_src1_mem == -1) {
                // 内存中没有位置，push 保存
                SymbolManager_.pushReg(REG.EAX, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", REG.EAX));
            } else {
                // 内存中有位置，更新内存中的值
                ASMLines.add(ASMConstructor.construct_asm("mov", eax_src1_mem, REG.EAX));
            }
        }

        // 备份 EDX
        String edx_symbol = SymbolManager_.rvalue(REG.EDX);
        Integer edx_mem = null;
        if (!SymbolManager_.useInfo(edx_symbol, true).noUse()) {
            edx_mem = SymbolManager_.avalueMem(edx_symbol);
            if (edx_mem == -1) {
                // 内存中没有位置，push 保存
                SymbolManager_.pushReg(REG.EDX, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", REG.EDX));
            } else {
                // 内存中有位置，更新内存中的值
                ASMLines.add(ASMConstructor.construct_asm("mov", edx_mem, REG.EDX));
            }
        }

        // MUL
        String op = TACLine_.op.commonop2String();
        ASMLines.add(ASMConstructor.construct_asm(op, reg_src2));
        SymbolManager_.setAvalueReg(SymbolManager_.encodeVar(str_dst), REG.EAX);

        return ASMLines;
    }
}